﻿using Furion;
using GWB.Core;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Furion.FriendlyException;
using GWB.Application.System.LogManage.Dtos;
using GWB.Application.System.LogManage.LogService;
using System.Reflection;
using System.Linq;
using GWB.Application.Common;

namespace GWB.System.Api.Handler
{
    /// <summary>
    /// 
    /// </summary>
    public class RequestAuditFilter : IAsyncActionFilter
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var watch = Stopwatch.StartNew();


            //============== 这里是执行方法之前获取数据 ====================
            // 获取控制器、路由信息
            var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
            // 获取请求的方法
            // 获取 HttpContext 和 HttpRequest 对象
            var httpContext = context.HttpContext;
            var httpRequest = httpContext.Request;

            // 获取客户端 Ipv4 地址
            var remoteIPv4 = httpContext.GetRemoteIpAddressToIPv4();
            // 获取请求的 Url 地址
            var requestUrl = httpRequest.GetRequestUrlAddress();
            // 获取来源 Url 地址
            var refererUrl = httpRequest.GetRefererUrlAddress();

            var method = httpRequest.Method;
            var path = httpRequest.Path;


            var methodInfo = CustomAttributeExtensions.GetCustomAttribute<AuthorizationAttribute>(actionDescriptor.MethodInfo);

            //============== 这里是执行方法之后获取数据 ====================
            var actionContext = await next();

            watch.Stop();

            _ = App.GetService<ILogService>().AddRequestLog(new RequestLogCreateOrUpdateInputDto()
            {
                IsError = actionContext.Exception != null, // 判断是否请求成功，没有异常就是请求成功
                ReturnResult = JsonConvert.SerializeObject(actionContext.Exception == null ?
                    (object)actionContext.Result : new UnifyResult<object>
                    {
                        Code = 500,
                        IsSuccess = false,
                        Errors = actionContext.Exception.Message,
                        Msg = "请求失败",
                        Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                    }),//返回的结果Annotation
                Ip = remoteIPv4,//Ipv4 地址
                Parameters = JsonConvert.SerializeObject(context.ActionArguments),//请求参数
                RequestUrl = requestUrl,//请求的 Url 地址
                RefererUrl = refererUrl,//来源 Url 地址
                Method = method,
                Path = path,
                ConsumedTime = (decimal)watch.Elapsed.TotalSeconds,
                Annotation = methodInfo?.Name ?? ""
            });
        }
    }
}
